frontend/pages/e/[uuid].tsx (view raw)
1import {useState, useReducer, useEffect} from 'react';
2import {useTranslation} from 'react-i18next';
3import {initializeApollo} from '../../lib/apolloClient';
4import useToastStore from '../../stores/useToastStore';
5import useEventStore from '../../stores/useEventStore';
6import Layout from '../../layouts/Default';
7import AddToMyEventDialog from '../../containers/AddToMyEventDialog';
8import TravelColumns from '../../containers/TravelColumns';
9import NewTravelDialog from '../../containers/NewTravelDialog';
10import WelcomeDialog from '../../containers/WelcomeDialog';
11import EventBar from '../../containers/EventBar';
12import Loading from '../../containers/Loading';
13import Fab from '../../containers/Fab';
14import OnBoardingTour from '../../containers/OnBoardingTour';
15import {
16 useUpdateEventMutation,
17 Event as EventType,
18 useEventByUuidQuery,
19 EventByUuidDocument,
20 EditEventInput,
21} from '../../generated/graphql';
22import ErrorPage from '../_error';
23
24const POLL_INTERVAL = 10000;
25
26interface Props {
27 event: EventType;
28 eventUUID: string;
29}
30
31const EventPage = props => {
32 const {t} = useTranslation();
33 const {event} = props;
34 if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
35 return <Event {...props} />;
36};
37
38const Event = (props: Props) => {
39 const {eventUUID} = props;
40 const {t} = useTranslation();
41 const addToast = useToastStore(s => s.addToast);
42 const setEvent = useEventStore(s => s.setEvent);
43 const eventUpdate = useEventStore(s => s.event);
44 const setIsEditing = useEventStore(s => s.setIsEditing);
45 const [updateEvent] = useUpdateEventMutation();
46 const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
47 const [openNewTravel, toggleNewTravel] = useReducer(i => !i, false);
48 const {data: {eventByUUID: event} = {}} = useEventByUuidQuery({
49 pollInterval: POLL_INTERVAL,
50 variables: {uuid: eventUUID},
51 });
52
53 useEffect(() => {
54 if (event) setEvent(event as EventType);
55 }, [event]);
56
57 const onSave = async e => {
58 try {
59 const {uuid, ...data} = eventUpdate;
60 const {id, __typename, travels, users, waitingList, ...input} = data;
61 await updateEvent({
62 variables: {uuid, eventUpdate: input as EditEventInput},
63 refetchQueries: ['eventByUUID'],
64 });
65 setIsEditing(false);
66 } catch (error) {
67 console.error(error);
68 addToast(t('event.errors.cant_update'));
69 }
70 };
71
72 const onShare = async () => {
73 if (!event) return null;
74 // If navigator share capability
75 if (!!navigator.share)
76 return await navigator.share({
77 title: `Caroster ${event.name}`,
78 url: `${window.location.href}`,
79 });
80 // Else copy URL in clipboard
81 else if (!!navigator.clipboard) {
82 await navigator.clipboard.writeText(window.location.href);
83 addToast(t('event.actions.copied'));
84 return true;
85 }
86 };
87
88 if (!event) return <Loading />;
89
90 return (
91 <Layout
92 pageTitle={t('event.title', {title: event.name})}
93 menuTitle={t('event.title', {title: event.name})}
94 displayMenu={false}
95 >
96 <EventBar
97 event={event}
98 onAdd={setIsAddToMyEvent}
99 onSave={onSave}
100 onShare={onShare}
101 />
102 <TravelColumns toggleNewTravel={toggleNewTravel} />
103 <Fab
104 color="primary"
105 open={openNewTravel}
106 onClick={toggleNewTravel}
107 aria-label="add-travel"
108 />
109 <NewTravelDialog open={openNewTravel} toggle={toggleNewTravel} />
110 <AddToMyEventDialog
111 event={event}
112 open={isAddToMyEvent}
113 onClose={() => setIsAddToMyEvent(false)}
114 />
115 <WelcomeDialog />
116 <OnBoardingTour />
117 </Layout>
118 );
119};
120
121export async function getServerSideProps(ctx) {
122 const {uuid} = ctx.query;
123 const apolloClient = initializeApollo();
124 const {data = {}} = await apolloClient.query({
125 query: EventByUuidDocument,
126 variables: {uuid},
127 });
128 const {eventByUUID: event} = data;
129 const {host = ''} = ctx.req.headers;
130
131 return {
132 props: {
133 event,
134 eventUUID: uuid,
135 metas: {
136 title: event?.name || '',
137 url: `https://${host}${ctx.resolvedUrl}`,
138 },
139 },
140 };
141}
142
143export default EventPage;